using B.S.Medical.Api.Read.Application.Command.Home;
using B.S.Medical.Api.Read.DTOS;
using B.S.Medical.Domain.Medical;
using B.S.Medical.Domain.Doctor;
using B.S.Medical.Domain.Department;
using B.S.Medical.ErrorCode;
using B.S.Medical.Infrastructure.Interface;
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace B.S.Medical.Api.Read.Application.Handler.Home
{
    public class GetRealTimeRegistersHandler : IRequestHandler<GetRealTimeRegistersCommand, ApiResult<List<RealTimeRegisterDto>>>
    {
        private readonly IBaseRepository<RegisterModel> _registerRepo;
        private readonly IBaseRepository<PatientModel> _patientRepo;
        private readonly IBaseRepository<DoctorModel> _doctorRepo;
        private readonly IBaseRepository<ManageModel> _departmentRepo;

        public GetRealTimeRegistersHandler(
            IBaseRepository<RegisterModel> registerRepo,
            IBaseRepository<PatientModel> patientRepo,
            IBaseRepository<DoctorModel> doctorRepo,
            IBaseRepository<ManageModel> departmentRepo)
        {
            _registerRepo = registerRepo;
            _patientRepo = patientRepo;
            _doctorRepo = doctorRepo;
            _departmentRepo = departmentRepo;
        }

        public async Task<ApiResult<List<RealTimeRegisterDto>>> Handle(GetRealTimeRegistersCommand request, CancellationToken cancellationToken)
        {
            var res = new ApiResult<List<RealTimeRegisterDto>>();
            try
            {
                // 1. 获取挂号记录
                var registers = _registerRepo.GetAll()
                    .Where(x => !x.IsDeleted)
                    .OrderByDescending(x => x.CreateTime)
                    .Take(request.Limit)
                    .ToList();

                // 如果没有挂号记录，直接返回空列表
                if (!registers.Any())
                {
                    res.Data = new List<RealTimeRegisterDto>();
                    res.Msg = "获取实时挂号数据成功!";
                    res.Code = ApiEnum.Success;
                    return await Task.FromResult(res);
                }

                // 2. 收集所有需要的ID
                var patientIds = registers.Select(r => r.PatientId).Distinct().ToList();
                var doctorIds = registers.Select(r => r.DoctorId).Distinct().ToList();

                // 3. 批量获取所有患者和医生信息
                var patients = _patientRepo.GetAll()
                    .Where(p => !p.IsDeleted && patientIds.Contains(p.Id))
                    .ToDictionary(p => p.Id);

                var doctors = _doctorRepo.GetAll()
                    .Where(d => !d.IsDeleted && doctorIds.Contains(d.Id))
                    .ToDictionary(d => d.Id);

                // 4. 收集所有科室ID
                var departmentIds = doctors.Values
                    .Select(d => d.DepartmentId)
                    .Distinct()
                    .ToList();

                // 5. 批量获取所有科室信息
                var departments = _departmentRepo.GetAll()
                    .Where(dep => !dep.IsDeleted && departmentIds.Contains(dep.Id))
                    .ToDictionary(dep => dep.Id);

                var result = new List<RealTimeRegisterDto>();

                // 6. 使用内存查找填充DTO
                foreach (var register in registers)
                {
                    patients.TryGetValue(register.PatientId, out var patient);
                    doctors.TryGetValue(register.DoctorId, out var doctor);
                    departments.TryGetValue(doctor?.DepartmentId ?? 0, out var department);

                    result.Add(new RealTimeRegisterDto
                    {
                        PatientName = patient?.Name ?? "未知患者",
                        Phone = patient?.Phone ?? "未知",
                        DepartmentName = department?.DepartmentName ?? "未知科室",
                        DoctorName = doctor?.DoctorName ?? "未知医生",
                        Fee = register.Fee,
                        RegisterTime = register.CreateTime
                    });
                }

                res.Data = result;
                res.Msg = "获取实时挂号数据成功!";
                res.Code = ApiEnum.Success;
            }
            catch (Exception ex)
            {
                res.Data = null;
                res.Msg = "获取实时挂号数据异常：" + ex.Message;
                res.Code = ApiEnum.Error;
            }
            return await Task.FromResult(res);
        }
    }
} 